home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok71.lha / ROM20 / ROM20.mod < prev    next >
Text File  |  1993-08-15  |  25KB  |  927 lines

  1.  
  2. (*********************************************************************
  3.  
  4.     :Program.    ROM20
  5.     :Contents.   Calculator to evaluate numeric expressions
  6.     :Contents.   like "sin(x)/epsilon*(time*7.2E3)"
  7.     :Contents.   Works in CON:-Windows
  8.     :Author.     Stefan Salewski
  9.     :Address.    Stefan Salewski, Stolper Weg 3, D-2160 Stade
  10.     :Copyright.  © 1992 by S. Salewski, SHAREWARE, see file ROM20.doc
  11.     :Language.   Oberon
  12.     :Translator. Amiga-Oberon-Compiler V2.14d
  13.     :History.    V1.0    11. MAY 1992
  14.  
  15. *********************************************************************)
  16.  
  17. MODULE ROM20;
  18.   IMPORT
  19.     ASCII,
  20.     AVL,
  21.     Beep,
  22.     Break, (* we don't really need it *)
  23.     Conversions,
  24.     Dos,       (* print results unbuffered   *)
  25.     Formula,   (* this module does all the work *)
  26.     Intuition, (* only to get the printwidth and DisplayBeep()*)
  27.     io,
  28.     LRC2:LongRealConversions2, (* from AMOK#58 *)
  29.     MATHLIB,
  30.     NoGuru,
  31.     Requests,
  32.     SecureDos,
  33.     Strings,
  34.     TF:TurboFiles; (* Version 2.1 *)
  35.  
  36.   CONST
  37.     Space=' ';
  38.     PrinterName="PRT:";
  39.     ConfigName="S:ROM20.config";
  40.     ValuesName="S:ROM20.values";
  41.     IsOn=" is on";
  42.     IsOff=" is off";
  43.     LastResultName="#";
  44.     UseVarName="x";
  45.     MaxDigits=14;
  46.     PME=7; (* Additional space in WriteReal() for -n.mE-123 *)
  47.     MaxCommands=43;
  48.     ResetColor="\e[0m";
  49.     Clear="\ec";
  50.     Color3="\e[33m";
  51.     CRString0=" ROM20 V1.0 This version is only for the AMOK-FD-Library";
  52.     CRString1=" A plain but powerful calculator for numeric expressions";
  53.     CRString2=" This program is not in the Public Domain, but SHAREWARE";
  54.     CRString3=" © 1992 by Stefan Salewski    (Type ? for help)";
  55.     OoM="Not enougth Memory!";
  56.     ImpossibleError="I thought this is an impossible error!";
  57.     NoError=0;
  58.     PrinterError=1;
  59.     FileWriteError=2;
  60.     VariationError=3;
  61.  
  62.   TYPE
  63.     String20=ARRAY 20 OF CHAR;
  64.     String80=ARRAY 80 OF CHAR;
  65.     String512=ARRAY 512 OF CHAR;
  66.     InfoText=ARRAY 4 OF String80;
  67.  
  68.   CONST
  69.     IText=InfoText("All ok",
  70.                    "Can't use printer",
  71.                    "Can't write to file",
  72.                    "Can't calculate variation"
  73.                   );
  74.  
  75.   TYPE
  76.     Command=RECORD
  77.               name:String20;
  78.               id:INTEGER;
  79.             END;
  80.     Commands=ARRAY MaxCommands OF Command;
  81.     ComNodePtr=POINTER TO ComNode;
  82.     ComNode= RECORD (AVL.SNode);
  83.                id:INTEGER
  84.              END;
  85.  
  86.   CONST (* Commands *)
  87.     Calculate=0;
  88.     Quit=1;  Point=2;
  89.     Help=3; Info=4; Questionmark=Help;
  90.     PrinterOn=5; PrinterOff=6;
  91.     OpenFile=7; CloseFile=8;
  92.     PrintResult=9; PrintAll=10;
  93.     LoadValues=11; SaveValues=12;
  94.     LoadConfig=13; SaveConfig=14;
  95.     FormulaOn=15; FormulaOff=16;
  96.     ExponentOn=17; ExponentOff=18;
  97.     LeftJustify=19; RightJustify=20;
  98.     AutoExpoOn=21; AutoExpoOff=22;
  99.     ShowCommands=23; ShowFunctions=24; ShowValues=25;
  100.     Format=26; SetFillChar=27;
  101.     RemoveValue=28; DisposeAllValues=29;
  102.     ResetStatistics=30; StatisticsUndo=31;
  103.     StatisticsOn=32; StatisticsOff=33;
  104.     SumOfInputs=34; MeanValue=35;
  105.     SumOfSquares=36; StatisticsCounter=37;
  106.     Variation=38; (* german Varianz *)
  107.     StandardDeviation=39; (* german StandardAbweichung or Streuung *)
  108.     TotalDigits=40; DigitsBehindPoint=41; Empty=42;
  109.  
  110.     Com=Commands('PrinterOn',PrinterOn,
  111.                  'PrinterOff',PrinterOff,
  112.                  'PrintResult',PrintResult,
  113.                  'PrintAll',PrintAll,
  114.                  'LoadValues',LoadValues,
  115.                  'SaveValues',SaveValues,
  116.                  'Quit',Quit,
  117.                  'Help',Help,
  118.                  '',Empty,
  119.                  '?',Questionmark,
  120.                  'ShowCommands',ShowCommands,
  121.                  'ShowFunctions',ShowFunctions,
  122.                  'ShowValues',ShowValues,
  123.                  'Format',Format,
  124.                  '.',Point,
  125.                  'OpenFile',OpenFile,
  126.                  'CloseFile',CloseFile,
  127.                  'LoadConfig',LoadConfig,
  128.                  'SaveConfig',SaveConfig,
  129.                  'RemoveValue',RemoveValue,
  130.                  'DisposeAllValues',DisposeAllValues,
  131.                  'FormulaOn',FormulaOn,
  132.                  'FormulaOff',FormulaOff,
  133.                  'ResetStatistics',ResetStatistics,
  134.                  'StatisticsOn',StatisticsOn,
  135.                  'StatisticsOff',StatisticsOff,
  136.                  'SumOfInputs',SumOfInputs,
  137.                  'MeanValue',MeanValue,
  138.                  'SumOfSquares',SumOfSquares,
  139.                  'Variation',Variation,
  140.                  'StandardDeviation',StandardDeviation,
  141.                  'StatisticsUndo',StatisticsUndo,
  142.                  'ExponentOn',ExponentOn,
  143.                  'ExponentOff',ExponentOff,
  144.                  'TotalDigits',TotalDigits,
  145.                  'DigitsBehindPoint',DigitsBehindPoint,
  146.                  'Info',Info,
  147.                  'StatisticsCounter',StatisticsCounter,
  148.                  'SetFillChar',SetFillChar,
  149.                  'LeftJustify',LeftJustify,
  150.                  'RightJustify',RightJustify,
  151.                  'AutoExpoOn',AutoExpoOn,
  152.                  'AutoExpoOff',AutoExpoOff
  153.                   );
  154.  
  155.   TYPE
  156.     Config=RECORD
  157.              gs:INTEGER;
  158.              nks:INTEGER;
  159.              expo:BOOLEAN;
  160.              autoExpo:BOOLEAN;
  161.              leftJustify:BOOLEAN;
  162.              printAll:BOOLEAN;
  163.              fillChar:CHAR;
  164.            END;
  165.  
  166.     Statistics=RECORD
  167.                  sum:LONGREAL;
  168.                  sumOfSquares:LONGREAL;
  169.                  lastInput:LONGREAL;
  170.                  counter:LONGINT;
  171.                  on:BOOLEAN;
  172.                  canUndo:BOOLEAN;
  173.                END;
  174.  
  175.     Settings=RECORD
  176.                lastResultIndex:INTEGER;
  177.                printWidth:INTEGER;
  178.                useVarIndex:INTEGER;
  179.                error:INTEGER;
  180.                filename:String80;
  181.                useFormulaExpression:String80;
  182.                printerOn:BOOLEAN;
  183.                fileOpen:BOOLEAN;
  184.                useFormula:BOOLEAN;
  185.              END;
  186.  
  187.   VAR
  188.     input,tmp1,tmp2:String512;
  189.     command:AVL.String;
  190.     root:AVL.SRoot;
  191.     el:AVL.SNodePtr;
  192.     formula:Formula.Formula;
  193.     useFormula:Formula.Formula;
  194.     file:TF.File;
  195.     printerPtr:Dos.FileHandlePtr;
  196.     config:Config;
  197.     statistics:Statistics;
  198.     settings:Settings;
  199.     l:LONGINT;
  200.     id:INTEGER;
  201.  
  202.   PROCEDURE ImpErr;
  203.   BEGIN Requests.Assert(FALSE,ImpossibleError)
  204.   END ImpErr;
  205.  
  206.   PROCEDURE WriteErrorLn(str:ARRAY OF CHAR);
  207.   (* $CopyArrays- *)
  208.   BEGIN
  209.     Beep.Beep(TRUE);
  210.     Intuition.DisplayBeep(NIL);
  211.     io.WriteString(str);
  212.     io.WriteLn;
  213.   END WriteErrorLn;
  214.  
  215.   PROCEDURE WriteString(str:ARRAY OF CHAR);
  216.   (* $CopyArrays- *)
  217.   VAR i:INTEGER;
  218.   BEGIN
  219.     io.WriteString(str);
  220.     IF settings.fileOpen THEN
  221.       IF NOT TF.WriteString(file,str) THEN
  222.         settings.error:=FileWriteError END;
  223.     END;
  224.     IF settings.printerOn THEN
  225.       i:=Strings.Length(str);
  226.       IF Dos.Write(printerPtr,str,i)<i THEN
  227.         settings.error:=PrinterError END;
  228.     END;
  229.   END WriteString;
  230.  
  231.   PROCEDURE Write(c:CHAR);
  232.   BEGIN
  233.     io.Write(c);
  234.     IF settings.fileOpen THEN
  235.       IF NOT TF.WriteChar(file,c) THEN
  236.         settings.error:=FileWriteError END;
  237.     END;
  238.     IF settings.printerOn THEN
  239.       IF Dos.Write(printerPtr,c,1)<1 THEN
  240.         settings.error:=PrinterError END;
  241.     END;
  242.   END Write;
  243.  
  244.   PROCEDURE WriteLn;
  245.   BEGIN
  246.     Write(ASCII.lf);
  247.   END WriteLn;
  248.  
  249.   PROCEDURE*  WriteStringLn(str:ARRAY OF CHAR);
  250.   (* $CopyArrays- *)
  251.   BEGIN
  252.     WriteString(str);
  253.     WriteLn;
  254.   END WriteStringLn;
  255.  
  256.   PROCEDURE WriteInt(l:LONGINT;n:INTEGER);
  257.     VAR
  258.       str:ARRAY 16 OF CHAR;
  259.   BEGIN
  260.     IF NOT Conversions.IntToString(l,str,n) THEN ImpErr END;
  261.     WriteStringLn(str);
  262.   END WriteInt;
  263.  
  264.   PROCEDURE WriteReal(x:LONGREAL);
  265.     VAR str: ARRAY (MaxDigits+PME) OF CHAR;
  266.   BEGIN
  267.     IF LRC2.RealToString(x,str,config.gs,config.nks,config.expo OR
  268.                          (config.autoExpo AND (ABS(x)<1)),
  269.                          config.leftJustify) THEN
  270.       WriteString(" =");
  271.       WriteStringLn(str)
  272.     ELSE
  273.       ImpErr;
  274.     END;
  275.   END WriteReal;
  276.  
  277.   PROCEDURE WriteRealRemember(x:LONGREAL);
  278.   BEGIN
  279.     WriteReal(x);
  280.     Formula.ChangeValue(settings.lastResultIndex,x)
  281.   END WriteRealRemember;
  282.  
  283.   PROCEDURE WriteFillChar(n:INTEGER);
  284.     VAR
  285.       str:ARRAY 256 OF CHAR;
  286.   BEGIN
  287.     IF n<0 THEN ImpErr END;
  288.     IF n>255 THEN n:=255 END;
  289.     str[n]:=0X;
  290.     WHILE n>0 DO
  291.       DEC(n);
  292.       str[n]:=config.fillChar
  293.     END;
  294.     WriteString(str);
  295.   END WriteFillChar;
  296.  
  297.   PROCEDURE AddCommandsToAVL;
  298.     VAR
  299.      el:ComNodePtr;
  300.      i:INTEGER;
  301.   BEGIN
  302.     i:=0;
  303.     WHILE i<MaxCommands DO
  304.       NEW(el);
  305.       Requests.Assert(el#NIL,OoM);
  306.       COPY(Com[i].name,el.name);
  307.       el.id:=Com[i].id;
  308.       IF NOT AVL.SAdd(root,el) THEN ImpErr END;
  309.       INC(i);
  310.     END;
  311.   END AddCommandsToAVL;
  312.  
  313.   PROCEDURE SaveConfigP(name:ARRAY OF CHAR):BOOLEAN;
  314.   (* $CopyArrays- *)
  315.     VAR
  316.       f:TF.File;
  317.       ok:BOOLEAN;
  318.   BEGIN
  319.     IF name="" THEN name:=ConfigName END;
  320.     IF TF.Open(f,name,SIZE(Config),TF.newFile) THEN
  321.       ok:=TF.Write(f,config);
  322.       RETURN TF.Close(f) AND ok;
  323.     ELSE
  324.       RETURN FALSE
  325.     END;
  326.   END SaveConfigP;
  327.  
  328.   PROCEDURE LoadConfigP(name:ARRAY OF CHAR):BOOLEAN;
  329.   (* $CopyArrays- *)
  330.     VAR
  331.       f:TF.File;
  332.       l:LONGINT;
  333.       ok:BOOLEAN;
  334.   BEGIN
  335.     IF name="" THEN name:=ConfigName END;
  336.     IF TF.Exists(name,l) AND (l=SIZE(Config)) THEN
  337.       IF TF.Open(f,name,SIZE(Config),TF.oldFile) THEN
  338.         ok:=TF.Read(f,config);
  339.         RETURN TF.Close(f) AND ok;
  340.       ELSE
  341.         RETURN FALSE
  342.       END;
  343.     ELSE
  344.       RETURN FALSE
  345.     END;
  346.   END LoadConfigP;
  347.  
  348.   PROCEDURE GetPrintWidth;
  349.     VAR
  350.       prefs:Intuition.Preferences;
  351.   BEGIN
  352.     Intuition.GetPrefs(prefs,SIZE(prefs));
  353.     settings.printWidth:=prefs.printRightMargin-prefs.printLeftMargin;
  354.   END GetPrintWidth;
  355.  
  356.   PROCEDURE InitLastResult;
  357.   BEGIN
  358.     IF NOT (Formula.DefineValue(LastResultName,0,TRUE,"") AND
  359.       Formula.GetIndex(LastResultName,settings.lastResultIndex)) THEN
  360.       ImpErr
  361.     END;
  362.   END InitLastResult;
  363.  
  364.   PROCEDURE InitUseVar;
  365.   BEGIN
  366.     IF NOT (Formula.DefineValue(UseVarName,0,TRUE,"") AND
  367.       Formula.GetIndex(UseVarName,settings.useVarIndex)) THEN
  368.       ImpErr
  369.     END;
  370.   END InitUseVar;
  371.  
  372.   PROCEDURE InitStatistics;
  373.   BEGIN
  374.     statistics.sum:=0;
  375.     statistics.sumOfSquares:=0;
  376.     statistics.lastInput:=0;
  377.     statistics.counter:=0;
  378.     statistics.on:=TRUE;
  379.     statistics.canUndo:=FALSE;
  380.   END InitStatistics;
  381.  
  382.   PROCEDURE InitConfig;
  383.   BEGIN
  384.     IF NOT LoadConfigP(ConfigName) THEN
  385.       config.gs:=8;
  386.       config.nks:=8;
  387.       config.expo:=FALSE;
  388.       config.autoExpo:=FALSE;
  389.       config.leftJustify:=TRUE;
  390.       config.printAll:=FALSE;
  391.       config.fillChar:=Space;
  392.     END;
  393.   END InitConfig;
  394.  
  395.   PROCEDURE InitSettings;
  396.   BEGIN
  397.     GetPrintWidth;
  398.     settings.lastResultIndex:=-1;
  399.     settings.useVarIndex:=-1;
  400.     settings.error:=NoError;
  401.     settings.filename:="";
  402.     settings.useFormulaExpression:="";
  403.     settings.printerOn:=FALSE;
  404.     settings.fileOpen:=FALSE;
  405.     settings.useFormula:=FALSE;
  406.   END InitSettings;
  407.  
  408.   PROCEDURE InitAll;
  409.   BEGIN
  410.     printerPtr:=NIL;
  411.     file.res:=TF.notOpen;
  412.     AVL.SInit(root);
  413.     AddCommandsToAVL;
  414.     InitStatistics;
  415.     InitConfig;
  416.     InitSettings;
  417.     InitLastResult;
  418.     IF Formula.LoadValues(ValuesName) THEN END;
  419.   END InitAll;
  420.  
  421.   PROCEDURE SetFillCharP(c:ARRAY OF CHAR);
  422.   (* $CopyArrays- *)
  423.   BEGIN
  424.     IF (c[0]='"') AND (c[1]#0X) AND (c[2]='"') THEN
  425.       config.fillChar:=c[1]
  426.     ELSE
  427.       config.fillChar:=c[0]
  428.     END
  429.   END SetFillCharP;
  430.  
  431.   PROCEDURE CalculateVariation():LONGREAL;
  432.   BEGIN
  433.     IF statistics.counter>1 THEN
  434.       RETURN (statistics.sumOfSquares-
  435.              (MATHLIB.SQR(statistics.sum)/statistics.counter))/
  436.              (statistics.counter-1);
  437.     ELSE
  438.       settings.error:=VariationError;
  439.       RETURN MAX(LONGREAL)
  440.     END;
  441.   END CalculateVariation;
  442.  
  443.   PROCEDURE UseFormula(expression:ARRAY OF CHAR);
  444.   (* $CopyArrays- *)
  445.   BEGIN
  446.     IF expression#"" THEN
  447.       IF NOT settings.useFormula AND
  448.         Formula.GetIndex(UseVarName,settings.useVarIndex) THEN
  449.         WriteStringLn('Attention: This changes value "x"')
  450.       END;
  451.       InitUseVar;
  452.       IF NOT Formula.Compile(expression,useFormula) THEN
  453.         IF NOT Formula.RemoveValue(UseVarName) THEN ImpErr END;
  454.         settings.useFormula:=FALSE;
  455.         io.WriteString("New Formula: ");
  456.         WriteErrorLn(Formula.ErrorText[useFormula.error]);
  457.       ELSE
  458.         COPY(expression,settings.useFormulaExpression);
  459.         settings.useFormula:=TRUE
  460.       END;
  461.     ELSE
  462.       IF settings.useFormula THEN
  463.         IF NOT Formula.RemoveValue(UseVarName) THEN ImpErr END;
  464.         settings.useFormula:=FALSE;
  465.       END;
  466.     END;
  467.   END UseFormula;
  468.  
  469.   PROCEDURE Printer(on:BOOLEAN);
  470.   BEGIN
  471.     IF on THEN
  472.       GetPrintWidth;
  473.       IF NOT settings.printerOn THEN
  474.         printerPtr:=SecureDos.Open(PrinterName,Dos.newFile);
  475.         IF printerPtr#NIL THEN
  476.           settings.printerOn:=TRUE
  477.         ELSE
  478.           (*settings.printerOn:=FALSE;*)
  479.           settings.error:=PrinterError;
  480.         END;
  481.       END;
  482.     ELSE
  483.       IF settings.printerOn THEN
  484.         SecureDos.Close(printerPtr);
  485.         printerPtr:=NIL;
  486.         settings.printerOn:=FALSE
  487.       END;
  488.     END;
  489.   END Printer;
  490.  
  491.   PROCEDURE OpenFileP(name:ARRAY OF CHAR);
  492.   (* $CopyArrays- *)
  493.   BEGIN
  494.     GetPrintWidth;
  495.     IF settings.fileOpen THEN
  496.       WriteErrorLn("A file is already open")
  497.     ELSE
  498.       IF name#"" THEN
  499.         settings.fileOpen:=TF.Open(file,name,1024,TF.newFile)
  500.       END;
  501.       IF NOT settings.fileOpen THEN
  502.         WriteErrorLn("Can't open file")
  503.       ELSE
  504.         COPY(name,settings.filename)
  505.       END;
  506.     END;
  507.   END OpenFileP;
  508.  
  509.   PROCEDURE CloseFileP;
  510.   BEGIN
  511.     IF settings.fileOpen THEN
  512.       IF NOT TF.Close(file) THEN ImpErr END;
  513.       settings.fileOpen:=FALSE;
  514.       settings.filename:="";
  515.     ELSE
  516.       WriteErrorLn("A file is not open")
  517.     END;
  518.   END CloseFileP;
  519.  
  520.   PROCEDURE DoStatistics(x:LONGREAL);
  521.   BEGIN
  522.     INC(statistics.counter);
  523.     statistics.sum:=statistics.sum+x;
  524.     statistics.sumOfSquares:=statistics.sumOfSquares+MATHLIB.SQR(x);
  525.     statistics.lastInput:=x;
  526.     (*statistics.on:=TRUE;*)
  527.     statistics.canUndo:=TRUE;
  528.   END DoStatistics;
  529.  
  530.   PROCEDURE StatisticsUndoP():BOOLEAN;
  531.   BEGIN
  532.     IF statistics.canUndo THEN
  533.       DEC(statistics.counter);
  534.       statistics.sum:=statistics.sum-statistics.lastInput;
  535.       statistics.sumOfSquares:=statistics.sumOfSquares-
  536.                                MATHLIB.SQR(statistics.lastInput);
  537.       statistics.lastInput:=0;
  538.       (*statistics.on:=TRUE;*)
  539.       statistics.canUndo:=FALSE;
  540.       RETURN TRUE
  541.     ELSE
  542.       RETURN FALSE
  543.     END;
  544.   END StatisticsUndoP;
  545.  
  546.   PROCEDURE Status;
  547.   BEGIN
  548.     WriteString("Status: ");
  549.     WriteStringLn(IText[settings.error]);
  550.     IF settings.error#NoError THEN
  551.       Beep.Beep(TRUE);
  552.       Intuition.DisplayBeep(NIL);
  553.     END;
  554.   END Status;
  555.  
  556.   PROCEDURE WriteStatistics;
  557.     VAR v:LONGREAL;
  558.   BEGIN
  559.     WriteString("Statistics");
  560.     IF statistics.on THEN
  561.       WriteStringLn(IsOn)
  562.     ELSE
  563.       WriteStringLn(IsOff)
  564.     END;
  565.     WriteString("Number of inputs: ");
  566.     WriteInt(statistics.counter,8);
  567.     WriteString("Sum of inputs: ");
  568.     WriteReal(statistics.sum);
  569.     WriteString("Sum of squares:");
  570.     WriteReal(statistics.sumOfSquares);
  571.     IF statistics.counter>1 THEN
  572.       WriteString("Meanvalue:");
  573.       WriteReal(statistics.sum/statistics.counter);
  574.       WriteString("Variation:");
  575.       v:=CalculateVariation();
  576.       WriteReal(v);
  577.       WriteString("Standarddeviation:");
  578.       WriteReal(MATHLIB.SQRT(v));
  579.     END;
  580.   END WriteStatistics;
  581.  
  582.   PROCEDURE InfoP;
  583.   BEGIN
  584.     WriteString(Color3);
  585.     Status;
  586.     WriteStringLn("\nStatistics:");
  587.     WriteString(ResetColor);
  588.     WriteStatistics;
  589.     WriteString(Color3);
  590.     WriteString("\nOutputformat:");
  591.     WriteString(ResetColor);
  592.     WriteString("\nTotal number of digits:     ");
  593.     WriteInt(config.gs,3);
  594.     WriteString("Digits behind decimalpoint: ");
  595.     WriteInt(config.nks,3);
  596.     WriteString("Exponent");
  597.     IF config.expo THEN
  598.       WriteStringLn(IsOn)
  599.     ELSIF config.autoExpo THEN
  600.       WriteStringLn(" is used if ABS(x)<1")
  601.     ELSE
  602.       WriteStringLn(IsOff)
  603.     END;
  604.     IF config.leftJustify THEN
  605.       WriteStringLn("Result is left justified")
  606.     ELSE
  607.       WriteStringLn("Result is right justified")
  608.     END;
  609.     IF config.printAll THEN
  610.       WriteStringLn("Input and result is printed")
  611.     ELSE
  612.       WriteStringLn("Only result is printed")
  613.     END;
  614.     WriteString("Fillcharacter is ");
  615.     IF (config.fillChar=Space) THEN
  616.       WriteString("Space")
  617.     ELSIF (config.fillChar=0X) THEN
  618.       WriteString("0X")
  619.     ELSE
  620.       Write(config.fillChar)
  621.     END;
  622.     WriteString(Color3);
  623.     WriteString("\n\nOther settings:");
  624.     WriteStringLn(ResetColor);
  625.     IF settings.useFormula THEN
  626.       WriteString("Formula ");
  627.       WriteString(settings.useFormulaExpression);
  628.       WriteStringLn(" is used")
  629.     ELSE
  630.       WriteStringLn("No Formula is used")
  631.     END;
  632.     WriteString("Printer");
  633.     IF settings.printerOn THEN
  634.       WriteStringLn(IsOn)
  635.     ELSE
  636.       WriteStringLn(IsOff);
  637.     END;
  638.     IF settings.fileOpen THEN
  639.       WriteString("File ");
  640.       WriteString(settings.filename);
  641.       WriteStringLn(" is open\n");
  642.     ELSE
  643.       WriteStringLn("A file is not open\n");
  644.     END;
  645.   END InfoP;
  646.  
  647.   PROCEDURE* WriteCommand(el:AVL.NodePtr);
  648.   BEGIN
  649.     IF el IS ComNode THEN
  650.       WriteStringLn(el(AVL.SNode).name);
  651.     END;
  652.   END WriteCommand;
  653.  
  654.   PROCEDURE ShowCommandsP;
  655.   BEGIN
  656.     WriteString(Color3);
  657.     WriteStringLn(" Type a numerical expression or one of the following commands");
  658.     WriteString(ResetColor);
  659.     AVL.DoForward(root,WriteCommand);
  660.     WriteLn;
  661.   END ShowCommandsP;
  662.  
  663.   PROCEDURE Copyright;
  664.   BEGIN
  665.     WriteString(Color3);
  666.     WriteStringLn(CRString0);
  667.     WriteStringLn(CRString1);
  668.     WriteStringLn(CRString2);
  669.     WriteStringLn(CRString3);
  670.     WriteStringLn(ResetColor);
  671.   END Copyright;
  672.  
  673.   PROCEDURE HelpP;
  674.   BEGIN
  675.     Copyright;
  676.     ShowCommandsP;
  677.   END HelpP;
  678.  
  679.   PROCEDURE GetFormat(f:ARRAY OF CHAR):BOOLEAN;
  680.   (* $CopyArrays- *)
  681.   VAR
  682.     ok:BOOLEAN;
  683.     f1:String80;
  684.     i:INTEGER;
  685.     gs,nks:LONGINT;
  686.     expo:BOOLEAN;
  687.   BEGIN
  688.     Formula.DeleteSpaces(f);
  689.     IF f="" THEN RETURN FALSE END;
  690.     i:=Strings.Length(f)-1;
  691.     IF f[i]='E' THEN
  692.       expo:=TRUE;
  693.       f[i]:=0X;
  694.     ELSE
  695.       expo:=FALSE
  696.     END;
  697.     IF Formula.Split(f,f1,'.') THEN END;
  698.     IF (f#'') THEN
  699.       ok:=Conversions.StringToInt(f,gs);
  700.     ELSE
  701.       gs:=config.gs; (* use old value *)
  702.       ok:=TRUE
  703.     END;
  704.     IF (f1#'') THEN
  705.       ok:=ok AND Conversions.StringToInt(f1,nks);
  706.     ELSE
  707.       nks:=config.nks; (* use old value *)
  708.     END;
  709.     IF ok AND (gs>0) AND (gs<=MaxDigits) AND (nks>=0)
  710.       AND (nks<=MaxDigits) THEN
  711.       config.expo:=expo;
  712.       config.gs:=SHORT(gs);
  713.       config.nks:=SHORT(nks);
  714.       RETURN TRUE;
  715.     ELSE
  716.       RETURN FALSE
  717.     END;
  718.   END GetFormat;
  719.  
  720.   PROCEDURE Calc;
  721.     VAR
  722.       lastChar:INTEGER;
  723.       name:AVL.String;
  724.       expression:String512;
  725.       comment:String80;
  726.       x:LONGREAL;
  727.       trash:BOOLEAN;
  728.   BEGIN;
  729.     Formula.Divide(input,name,expression,comment);
  730.     IF NOT (Formula.Compile(expression,formula) AND
  731.            Formula.Evaluate(formula,x)) THEN
  732.       WriteErrorLn(Formula.ErrorText[formula.error]);
  733.       RETURN;
  734.     END;
  735.     IF settings.useFormula THEN
  736.       Strings.Insert(expression,0,"Formula(");
  737.       Strings.AppendChar(expression,")");
  738.       Formula.ChangeValue(settings.useVarIndex,x);
  739.       IF NOT Formula.Evaluate(useFormula,x) THEN
  740.         io.WriteString("Using Formula: ");
  741.         WriteErrorLn(Formula.ErrorText[useFormula.error]);
  742.         RETURN;
  743.       END;
  744.     END;
  745.     IF statistics.on THEN DoStatistics(x) END;
  746.     IF name#'' THEN
  747.       lastChar:=Strings.Length(name)-1;
  748.       IF name[lastChar]=":" THEN
  749.         trash:=FALSE;
  750.         name[lastChar]:=0X;
  751.         Formula.DeleteSpaces(name);
  752.       ELSE
  753.         trash:=TRUE
  754.       END;
  755.       lastChar:=Strings.Length(name);
  756.       IF Formula.DefineValue(name,x,trash,comment) THEN
  757.         WriteString(name);
  758.         IF config.printAll THEN
  759.           WriteString(" := ");
  760.           INC(lastChar,4);
  761.         END;
  762.       ELSE
  763.         WriteErrorLn('Name is not correct')
  764.       END;
  765.     ELSE
  766.       lastChar:=0;
  767.     END;
  768.     IF config.printAll THEN
  769.       WriteString(expression);
  770.       IF config.leftJustify THEN INC(lastChar,config.gs)
  771.       ELSE INC(lastChar,MaxDigits) END;
  772.       INC(lastChar,Strings.Length(expression)+(PME+2+1));
  773.         (* +2 for "= ", +1 for security *)
  774.       IF lastChar>=settings.printWidth THEN
  775.         WriteLn;
  776.       ELSE
  777.         WriteFillChar(settings.printWidth-lastChar);
  778.       END
  779.     END;
  780.     WriteRealRemember(x);
  781.   END Calc;
  782.  
  783. BEGIN
  784.   InitAll;
  785.   io.WriteString(Clear);
  786.   Copyright;
  787.   LOOP
  788.     io.WriteString(" : ");
  789.     io.ReadString(input);
  790.     Formula.DeleteSpaces(input);
  791.     tmp1:=input;
  792.     IF Formula.Split(tmp1,tmp2,Space) THEN
  793.       Formula.DeleteSpaces(tmp2);
  794.     END;
  795.     COPY(tmp1,command);
  796.     el:=AVL.SFind(root,command);
  797.     IF el#NIL THEN (* el IS ComNode *)
  798.       id:=el(ComNode).id;
  799.       IF id#Empty THEN io.WriteLn END;
  800.     ELSE
  801.       id:=Calculate;
  802.     END;
  803.     CASE id OF
  804.       Empty:WriteLn|
  805.       Calculate:Calc|
  806.       Quit,Point:EXIT|
  807.       Help:HelpP|
  808.       Info:InfoP|
  809.       ShowCommands:ShowCommandsP|
  810.       ShowFunctions:Formula.WriteFunctions(WriteStringLn);WriteLn|
  811.       ShowValues:Formula.WriteValues(WriteStringLn);WriteLn|
  812.       ResetStatistics:InitStatistics|
  813.       StatisticsOn:statistics.on:=TRUE|
  814.       StatisticsOff:statistics.on:=FALSE|
  815.       SetFillChar:SetFillCharP(tmp2)|
  816.       Format:IF NOT GetFormat(tmp2) THEN
  817.        WriteErrorLn("Format is not correct");
  818.       END|
  819.       FormulaOff:UseFormula("")|
  820.       FormulaOn:UseFormula(tmp2)|
  821.       PrinterOn:Printer(TRUE)|
  822.       PrinterOff:Printer(FALSE)|
  823.       PrintAll:config.printAll:=TRUE|
  824.       PrintResult:config.printAll:=FALSE|
  825.       OpenFile:OpenFileP(tmp2)|
  826.       CloseFile:CloseFileP|
  827.       LeftJustify:config.leftJustify:=TRUE|
  828.       RightJustify:config.leftJustify:=FALSE|
  829.       ExponentOn:config.expo:=TRUE|
  830.       ExponentOff:config.expo:=FALSE|
  831.       AutoExpoOn:config.autoExpo:=TRUE|
  832.       AutoExpoOff:config.autoExpo:=FALSE|
  833.       DisposeAllValues:
  834.         IF settings.useFormula THEN
  835.           WriteErrorLn("Can't dispose values if Formula is on")
  836.         ELSE
  837.           Formula.DisposeAllValues;
  838.           InitLastResult;
  839.         END|
  840.       LoadConfig:
  841.         IF tmp2="" THEN tmp2:=ConfigName END;
  842.         IF NOT LoadConfigP(tmp2) THEN
  843.           WriteErrorLn("Can't load configuration");
  844.         END|
  845.       SaveConfig:
  846.         IF tmp2="" THEN tmp2:=ConfigName END;
  847.         IF NOT SaveConfigP(tmp2) THEN
  848.           WriteErrorLn("Can't save configuration");
  849.         END|
  850.       LoadValues:
  851.         IF tmp2="" THEN tmp2:=ValuesName END;
  852.         IF NOT Formula.LoadValues(tmp2) THEN
  853.           WriteErrorLn("Can't load values");
  854.         END|
  855.       SaveValues:
  856.         IF tmp2="" THEN tmp2:=ValuesName END;
  857.         IF NOT Formula.SaveValues(tmp2) THEN
  858.           WriteErrorLn("Can't save values");
  859.         END|
  860.       RemoveValue:
  861.         IF settings.useFormula THEN
  862.           WriteErrorLn("Can't remove value if Formula is on")
  863.         ELSE
  864.           IF NOT Formula.RemoveValue(tmp2) THEN
  865.             WriteErrorLn("Can't remove this value")
  866.           END
  867.         END|
  868.       DigitsBehindPoint:
  869.         IF Conversions.StringToInt(tmp2,l) AND (l>=0)
  870.           AND (l<=MaxDigits) THEN
  871.           config.nks:=SHORT(l)
  872.         ELSE
  873.           WriteErrorLn("Wrong number of digits behind the decimal point")
  874.         END|
  875.       TotalDigits:
  876.         IF Conversions.StringToInt(tmp2,l) AND (l>0)
  877.           AND (l<=MaxDigits) THEN
  878.           config.gs:=SHORT(l)
  879.         ELSE
  880.           WriteErrorLn("Wrong number of total digits")
  881.         END|
  882.       StatisticsUndo:
  883.         IF NOT StatisticsUndoP() THEN
  884.           WriteErrorLn("Can't undo last operation")
  885.         END|
  886.       SumOfInputs:
  887.         WriteRealRemember(statistics.sum)|
  888.       MeanValue:
  889.         IF statistics.counter>0 THEN
  890.           WriteRealRemember(statistics.sum/statistics.counter)
  891.         ELSE
  892.           WriteErrorLn("Number of inputs is zero")
  893.         END|
  894.       SumOfSquares:
  895.         WriteRealRemember(statistics.sumOfSquares)|
  896.       StatisticsCounter:
  897.         WriteInt(statistics.counter,8);
  898.         Formula.ChangeValue(settings.lastResultIndex,
  899.                             statistics.counter)|
  900.       Variation:
  901.         IF statistics.counter>1 THEN
  902.           WriteRealRemember(CalculateVariation())
  903.         ELSE
  904.           WriteErrorLn("Can't calculate Variation")
  905.         END|
  906.       StandardDeviation:
  907.         IF statistics.counter>1 THEN
  908.           WriteRealRemember(MATHLIB.SQRT(CalculateVariation()));
  909.         ELSE
  910.           WriteErrorLn("Can't calculate Standarddeviation")
  911.         END|
  912.     ELSE
  913.       ImpErr
  914.     END;
  915.   END;
  916.  
  917. CLOSE
  918.   Status;
  919.   IF settings.printerOn THEN
  920.     SecureDos.Close(printerPtr);
  921.   END;
  922.   IF settings.fileOpen THEN
  923.     IF TF.Close(file) THEN END;
  924.   END;
  925. END ROM20.
  926.  
  927.